package com.hengfoxwolf.commonbase.base.adapter
import android.content.Context
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.recyclerview.widget.RecyclerView

abstract class BaseRvAdapter<T, B : ViewDataBinding>(
    private val dataSet: MutableList<T>? = null
) : RecyclerView.Adapter<BaseRvAdapter<T, B>.ViewHolder>() {

    protected var mContext: Context? = null
    protected var mOnItemClickListener: IOnItemClickListener<T>? = null
    protected var mOnItemLongClickListener: IOnItemLongClickListener<T>? = null

    var itemDataSet: MutableList<T>? = dataSet

    inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
        lateinit var binding: B
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        if (mContext == null) {
            mContext = parent.context
        }
        val binding: B =
            DataBindingUtil.inflate(LayoutInflater.from(mContext), getLayoutId(), parent, false)
        val holder = ViewHolder(binding.root)
        holder.binding = binding
        listenerWithBinding(binding)
        return holder
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        holder.binding.executePendingBindings()
        itemDataSet?.let {
            val dataBean = itemDataSet!![position]
            bindData(holder, dataBean, position)
            holder.binding.root.id = position
            holder.binding.root.tag = dataBean
        }
    }

    override fun getItemCount(): Int = itemDataSet?.size ?: 0

    override fun getItemViewType(position: Int): Int {
        return super.getItemViewType(position)
    }

    abstract fun getLayoutId(): Int

    abstract fun bindData(holder: ViewHolder, dataItem: T, position: Int)

    open fun listenerWithBinding(binding: B) {}

    fun setOnItemClickListener(mOnItemClickListener: IOnItemClickListener<T>? = null) {
        this.mOnItemClickListener = mOnItemClickListener
    }

    fun setOnItemLongClickListener(mOnItemLongClickListener: IOnItemLongClickListener<T>? = null) {
        this.mOnItemLongClickListener = mOnItemLongClickListener
    }

    fun setItemDataSet(itemDataSet: MutableList<T>, addInLast: Boolean = true) {
        Log.d(TAG, "${TAG}---setItemDataSet")
        val itemDataSetCount = this.itemDataSet?.size ?: 0
        if (itemDataSetCount == 0) {
            this.itemDataSet = mutableListOf()
        }
        this.itemDataSet?.let {
            if (addInLast) {
                it.addAll(itemDataSet)
                notifyItemRangeInserted(itemDataSetCount, itemDataSet.size)
            } else {
                it.addAll(0, itemDataSet)
                notifyItemRangeInserted(0, itemDataSet.size)
            }
        }
    }

    fun addItemData(itemData: T) {
        val itemDataSetCount = itemDataSet?.size ?:0
        if (itemDataSetCount == 0) {
            this.itemDataSet = mutableListOf()
        }
        itemDataSet?.apply {
            add(itemData)
            notifyItemRangeInserted(itemDataSetCount, 1)
        }
    }

    fun addItemData(itemData: T, position: Int) {
        val itemDataSetCount = itemDataSet?.size ?: 0
        if (itemDataSetCount == 0) {
            this.itemDataSet = mutableListOf()
        }
        itemDataSet?.apply {
            val newPosition = itemDataSetCount.coerceAtMost(0.coerceAtLeast(position))
            add(newPosition, itemData)
            notifyItemRangeInserted(newPosition, 1)
        }
    }

    fun removeItemDataSet() {
        itemDataSet?.apply {
            val thisSize = this.size
            this.clear()
            notifyItemRangeRemoved(0, thisSize)
        }
    }

    fun removeItemData(itemData: T) {
        itemDataSet?.apply {
            var position = -1
            for (index in this.indices) {
                if (itemData == itemDataSet!![index]) {
                    position = index
                    break
                }
            }
            if (position != -1) {
                this.removeAt(position)
                notifyItemRemoved(position)
            }
        }
    }

    fun removeItemData(position: Int) {
        itemDataSet?.apply {
            if (position in this.indices) {
                this.removeAt(position)
                notifyItemRemoved(position)
            }
        }
    }

    interface IOnItemClickListener<T> {
        /*
         * dataItem:获取的数据
         * position:数据位置
         * viewId:view标识,用于区分同一position,不同view之间的相同的click事件,比如:v1.onItemClick,v2.onItemClick
         * */
        fun onItemClick(dataItem: T, position: Int, viewId: Int)
    }

    interface IOnItemLongClickListener<T> {
        /*
         * dataItem:获取的数据
         * position:数据位置
         * viewId:view标识,用于区分同一position,不同view之间的相同的longClick事件,比如:v1.onItemLongClick,v2.onItemLongClick
         * */
        fun onItemLongClick(dataItem: T, position: Int, viewId: Int)
    }

    companion object {
        const val TAG = "BaseRvAdapter"
    }
}